<?php
/**
 * PatientSignal model class file.
 *
 * @package   models
 * @since     1.0
 * @filesource
 */

/**
 * This is the model class for table "{{patient_signal}}".
 * This is a DAO class which is used by DisorderController or other controllers
 * to operate data in database or return data in a specified format.
 *
 * The followings are the available columns in table '{{patient_signal}}':
 * @property integer $id
 * @property string $subject
 * @property string $dateOfBirth
 * @property integer $ageYear
 * @property integer $ageMonth
 * @property integer $gender
 * @property integer $disorderId
 * @property string $severity
 * @property string $createDate
 * @property string $recordingTime
 * @property integer $organizationId
 * @property string $pastDiagnosticHistory
 * @property string $currentMedicationAndDosage
 * @property string $reportedSideEffects
 * @property string $pastMedicationHistory
 * @property string $lastDoseTakenTime
 * @property string $otherTherapyDescription
 * @property string $interviewerName
 * @property string $interviewerQualification
 * @property string $interviewerAccreditationReference
 * @property string $interviewerAccreditationDate
 * @property string $interviewerAccreditingInstituteLocation
 * @property string $interviewerAccreditingTrainerExaminer
 * @property string $technologistName
 * @property string $technologistQualification
 * @property string $technologistEVestGReference
 * @property string $electrodeBrand
 * @property string $electrodeBatchNumber
 * @property string $electrodeConductiveGelBrand
 * @property string $electrodeConductiveGelBatchNumber
 * @property integer $userId
 * @property integer $status
 * @property string $signalPath
 * @property string $resultFileName
 *
 * The followings are the available model relations:
 * @property User $user - a User object related to the PatientSignal object
 * @property Disorder $disorder - a Disorder object related to the PatientSignal object
 * @property Organization $organization - a Organization object related to the PatientSignal object.
 * @property PatientSignalFile[] $signalFiles an array of PatientSignalFile object related to the PatientSignal object.
 */
class PatientSignal extends CActiveRecord
{

	/**
	 * @var int Status that signal files is not processed.
	 */
	const STATUS_NOT_PROCESSED=0;

	/**
	 * @var status that signal files is being processed.
	 */
	const STATUS_PROCESSING=1;

	/**
	 * @var status that signal files has been processed.
	 */
	const STATUS_PROCESSED=2;

	/**
	 * Returns the static model of the specified AR class.
	 * @return PatientSignal the static model class
	 */
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * Returns the table name related to this model class.
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return '{{patient_signal}}';
	}

	/**
	 * Returns the validation rules.
	 * The rules will be used when requesting validation by call self.validate().
	 * Many class method will call self.validate(), eg: CActiveRecord.save().
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		return array(
		// required attributes
		array('subject, dateOfBirth, disorderId, ageYear, ageMonth, gender, recordingTime, interviewerName, interviewerQualification, technologistName, technologistQualification, electrodeBrand, electrodeBatchNumber, electrodeConductiveGelBrand, electrodeConductiveGelBatchNumber, status, signalPath', 'required'),
		// set to empty string if no user input
		array('interviewerAccreditationReference, interviewerAccreditingInstituteLocation, technologistEVestGReference', 'default','value'=>''),		
		array('ageYear, ageMonth, gender, disorderId, organizationId, userId, status', 'numerical', 'integerOnly'=>true),
		array('subject, severity, interviewerName, interviewerQualification, interviewerAccreditationReference, 
		interviewerAccreditingInstituteLocation, interviewerAccreditingTrainerExaminer, technologistName, 
		technologistQualification, technologistEVestGReference, electrodeBrand, electrodeBatchNumber, 
		electrodeConductiveGelBrand, electrodeConductiveGelBatchNumber, 
		signalPath, resultFileName', 'length', 'max'=>255),
		array('dateOfBirth, pastDiagnosticHistory, currentMedicationAndDosage, interviewerAccreditationDate, reportedSideEffects, pastMedicationHistory, lastDoseTakenTime, otherTherapyDescription', 'safe'),
		// subject is used in generating filename so it must be letters and digits
		array('subject', 'match', 'pattern'=>'/^[0-9a-zA-z_\-]+$/','message'=>'{attribute} is invalid. Must be letters and digits only.'),
		array('interviewerAccreditationDate, lastDoseTakenTime, dateOfBirth', 'default','value'=>null),
		// The following rule is used by update().
		array('subject, dateOfBirth, ageYear, ageMonth, gender, disorderId, severity, recordingTime, pastDiagnosticHistory, 
				currentMedicationAndDosage, reportedSideEffects, pastMedicationHistory, lastDoseTakenTime, otherTherapyDescription, 
				interviewerName, interviewerQualification, interviewerAccreditationReference, interviewerAccreditationDate, 
				interviewerAccreditingInstituteLocation, interviewerAccreditingTrainerExaminer, 
				technologistName, technologistQualification, technologistEVestGReference, 
				electrodeBrand, electrodeBatchNumber, electrodeConductiveGelBrand, electrodeConductiveGelBatchNumber',
				'safe','on'=>'update'),
		// user cannot update these attributes in update signal
		array('id, createDate, organizationId, 
				userId, status, signalPath, resultFileName',
				'unsafe','on'=>'update'),
		// The following rule is used by search().
		array('id, subject, dateOfBirth, ageYear, ageMonth, gender, 
		disorderId, severity, createDate, recordingTime, organizationId, 
		pastDiagnosticHistory, currentMedicationAndDosage, 
		reportedSideEffects, pastMedicationHistory, lastDoseTakenTime, 
		otherTherapyDescription, interviewerName, interviewerQualification, interviewerAccreditationReference, 
		interviewerAccreditationDate, interviewerAccreditingInstituteLocation, interviewerAccreditingTrainerExaminer, 
		technologistName, technologistQualification, technologistEVestGReference, electrodeBrand, electrodeBatchNumber, 
		electrodeConductiveGelBrand, electrodeConductiveGelBatchNumber, 
		userId, status, signalPath, resultFileName', 'safe', 'on'=>'search'),		
		);
	}

	/**
	 * Returns the relationship between this Model class and other Model class
	 * based on foreign key constraint between corresponding tables.
	 * The relationships involved in this application involves HAS_MANY, HAS_ONE, BELONGS_TO,
	 * please refer to Yii document for details.
	 * @return array relational rules.
	 */
	public function relations()
	{
		return array(
			// one patient signal is related to one user.
			'user' => array(self::BELONGS_TO, 'User', 'userId'),
			// one patient signal is related to one disorder.
			'disorder' => array(self::BELONGS_TO, 'Disorder', 'disorderId'),
			// one patient signal is related to one organization.
			'organization' => array(self::BELONGS_TO, 'Organization', 'organizationId'),
			// one patient signal has many signal files.
			'signalFiles' => array(self::HAS_MANY, 'PatientSignalFile', 'patientSignalId',
				// returned array of signalFiles ordered by filename in ascendent order.
				'order'=>'filename ASC'
				),
			// signalFilesCount is a static relation to return the number of patientSignalFiles related to the patient signal.
			'signalFilesCount' => array(self::STAT, 'PatientSignalFile', 'patientSignalId'),
		);
	}

	/**
	 * Returns behaviors array
	 * @return array.
	 * @see CModel::behaviors()
	 */
	public function behaviors(){
		return array(
			// This setting will populate createTime variable automatically when 
			// creating an organization.
	  		'CTimestampBehavior' => array(
	  			'class' => 'zii.behaviors.CTimestampBehavior',
	  			'createAttribute' => 'createDate',
				'updateAttribute' => null,
			)
		);
	}

	/**
	 * Returns the labels for each column variables. 
	 * This will be used to render label on page.
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'id' => 'ID',
			'subject' => 'Subject Identifier',
			'dateOfBirth' => 'Date Of Birth',
			'ageYear' => 'Age Year',
			'ageMonth' => 'Age Month',
			'gender' => 'Gender',
			'disorderId' => 'Disorder',
			'severity' => 'Severity',
			'createDate' => 'Create Date',
			'recordingTime' => 'Recording Time',
			'organizationId' => 'Organization',
			'pastDiagnosticHistory' => 'Past Diagnostic History',
			'currentMedicationAndDosage' => 'Current Medication And Dosage',
			'reportedSideEffects' => 'Reported Side Effects',
			'pastMedicationHistory' => 'Past Medication History',
			'lastDoseTakenTime' => 'Time Last Dose Taken',
			'otherTherapyDescription' => 'Other Therapy Description',
			'interviewerName' => 'Interviewer Name',
			'interviewerQualification' => 'Interviewer Qualification',
			'interviewerAccreditationReference' => 'Interviewer Accreditation Reference',
			'interviewerAccreditationDate' => 'Interviewer Accreditation Date',
			'interviewerAccreditingInstituteLocation' => 'Interviewer Accrediting Institute Location',
			'interviewerAccreditingTrainerExaminer' => 'Interviewer Accrediting Trainer Examiner',
			'technologistName' => 'Technologist Name',
			'technologistQualification' => 'Technologist Qualification',
			'technologistEVestGReference' => 'Technologist Evest Greference',
			'electrodeBrand' => 'Electrode Brand',
			'electrodeBatchNumber' => 'Electrode Batch Number',
			'electrodeConductiveGelBrand' => 'Electrode Conductive Gel Brand',
			'electrodeConductiveGelBatchNumber' => 'Electrode Conductive Gel Batch Number',
			'userId' => 'User',
			'status' => 'Status',
			'signalPath' => 'Signal Path',
			'resultFileName' => 'Result File Name',
		);
	}

	/**
	 * Delete the record and also delete the files on the disk.
	 * This metod will rewrite the delete method inherited from CActiveRecord to delete patient signal file store on server.
	 * @see CActiveRecord::delete()
	 */
	public function delete(){
		// delete any signal files
		$signalFiles=$this->signalFiles;
		foreach ($signalFiles as $signalFile){
			$signalFile->delete();
		}

		//delete the result file if set.
		if (!empty($this->resultFileName)) {
			// if the file type data is not empty check if the file exists.
			$filePath=$this->signalPath.DIRECTORY_SEPARATOR.$this->resultFileName;
			if (file_exists($filePath)) {
				// if the file exists, delete the file.
				@unlink($filePath);
			}
		}
		parent::delete();
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search()
	{
		$criteria=new CDbCriteria;

		$criteria->compare('id',$this->id);
		$criteria->compare('subject',$this->subject,true);
		$criteria->compare('dateOfBirth',$this->dateOfBirth,true);
		$criteria->compare('ageYear',$this->ageYear);
		$criteria->compare('ageMonth',$this->ageMonth);
		$criteria->compare('gender',$this->gender);
		$criteria->compare('disorderId',$this->disorderId);
		$criteria->compare('severity',$this->severity,true);
		$criteria->compare('createDate',$this->createDate,true);
		$criteria->compare('recordingTime',$this->recordingTime,true);
		$criteria->compare('organizationId',$this->organizationId);
		$criteria->compare('pastDiagnosticHistory',$this->pastDiagnosticHistory,true);
		$criteria->compare('currentMedicationAndDosage',$this->currentMedicationAndDosage,true);
		$criteria->compare('reportedSideEffects',$this->reportedSideEffects,true);
		$criteria->compare('pastMedicationHistory',$this->pastMedicationHistory,true);
		$criteria->compare('lastDoseTakenTime',$this->lastDoseTakenTime,true);
		$criteria->compare('otherTherapyDescription',$this->otherTherapyDescription,true);
		$criteria->compare('interviewerName',$this->interviewerName,true);
		$criteria->compare('interviewerQualification',$this->interviewerQualification,true);
		$criteria->compare('interviewerAccreditationReference',$this->interviewerAccreditationReference,true);
		$criteria->compare('interviewerAccreditationDate',$this->interviewerAccreditationDate,true);
		$criteria->compare('interviewerAccreditingInstituteLocation',$this->interviewerAccreditingInstituteLocation,true);
		$criteria->compare('interviewerAccreditingTrainerExaminer',$this->interviewerAccreditingTrainerExaminer,true);
		$criteria->compare('technologistName',$this->technologistName,true);
		$criteria->compare('technologistQualification',$this->technologistQualification,true);
		$criteria->compare('technologistEVestGReference',$this->technologistEVestGReference,true);
		$criteria->compare('electrodeBrand',$this->electrodeBrand,true);
		$criteria->compare('electrodeBatchNumber',$this->electrodeBatchNumber,true);
		$criteria->compare('electrodeConductiveGelBrand',$this->electrodeConductiveGelBrand,true);
		$criteria->compare('electrodeConductiveGelBatchNumber',$this->electrodeConductiveGelBatchNumber,true);
		$criteria->compare('userId',$this->userId);
		$criteria->compare('status',$this->status);
		$criteria->compare('signalPath',$this->signalPath,true);
		$criteria->compare('resultFileName',$this->resultFileName,true);

		return new CActiveDataProvider(get_class($this), array(
			'criteria'=>$criteria,
		));
	}
	
	/**
	 * Get readable status of current patient signal's status.
	 * @return string
	 */
	public function getReadableStatus() {
		switch ($this->status) {
			case self::STATUS_NOT_PROCESSED:
				return 'Not Processed';
				break;
			case self::STATUS_PROCESSING:
				return 'Processing';
				break;
			case self::STATUS_PROCESSED:
				return 'Processed';
				break;
			
		}
	}
	
	
	/**
	 * Return if the patient signal is editatble. If it is not processed, it is editable, otherwise, not.
	 * @return boolean true|false is editable or not.
	 */
	public function isEditable() {
		return $this->status==PatientSignal::STATUS_NOT_PROCESSED;
	}
}